<template>
  <div>
    <vxe-modal
      :title="$t('common.title.select', '选择')"
      v-model="show"
      :loading="loading"
      :mask="false"
      :lock-view="false"
      width="80vw"
      height="90vh"
      destroy-on-close
      show-zoom
      remember
      resize
      show-footer
    >
      <div class="page-container">
        <!-- 搜索表单 -->
        <div class="search-form" ref="searchForm">
          <el-form ref="refForm" :model="formParams" :inline="true">
            <el-form-item
              :label="$t('common.field.keyword', '关键字')"
              prop="keyword"
            >
              <el-input
                style="width: 220px"
                v-model="formParams.keyword"
                :placeholder="$p('common.field.keyword', '关键字')"
              />
            </el-form-item>
            <el-form-item>
              <div style="margin-left: 10px">
                <el-button type="primary" icon="Search" @click="loadFiles">
                  {{ $t('common.action.search', '查询') }}
                </el-button>
                <el-button type="info" icon="Refresh" @click="resetForm">
                  {{ $t('common.action.reset', '重置') }}
                </el-button>
                <el-button type="success" icon="Upload" @click="handleUpload">
                  {{ $t('common.action.upload', '上传') }}
                </el-button>
                <el-button type="danger" icon="Delete" @click="handleDelete">
                  {{ $t('common.action.batch_delete', '批量删除') }}
                </el-button>
              </div>
            </el-form-item>
          </el-form>
        </div>
        <!-- 文件 Grid -->
        <div>
          <div class="grid-container" v-if="files.length > 0">
            <!-- 如果有文件 -->
            <el-card
              class="card-container"
              :class="{ selected: isSelected(file.id) }"
              shadow="never"
              v-for="(file, index) in files"
              :key="index"
              @click="toggleSelection(file)"
            >
              <el-image
                v-if="file.mime.includes('image')"
                class="image-container"
                fit="cover"
                :src="file.url"
                :alt="file.name"
              ></el-image>
              <div class="image-container font-image" v-else>
                {{ file.extension }}
              </div>

              <template #footer>
                <el-text class="title" truncated>
                  {{ file.name }}
                </el-text>
              </template>
            </el-card>
          </div>
          <!-- 如果没有 -->
          <div v-else class="empty-state">
            <el-empty
              :description="$t('common.message.info.empty', '暂无数据！')"
            />
          </div>
        </div>
      </div>
      <template #footer>
        <!-- 分页 -->
        <vxe-pager
          align="left"
          v-model:current-page="pageParams.currentPage"
          v-model:page-size="pageParams.pageSize"
          :total="pageParams.total"
          @page-change="pageChangeEvent"
        />
        <el-button type="info" icon="Close" @click="selectedCancel">
          {{ $t('common.action.cancel', '取消') }}
        </el-button>
        <el-button type="primary" icon="Check" @click="selectedConfirm">
          {{ $t('common.action.confirm', '确定') }}
        </el-button>
      </template>
    </vxe-modal>
    <!-- 文件上传 -->
    <ra-upload ref="refRaUpload" @reload="loadFiles" />
  </div>
</template>

<script setup>
import { smartTranslate as $t, transPlaceholder as $p } from '@/lang';
import AdminFileAPI from '@/api/admin/admin/file';

/**
 * 使用方法：
 * 1. 父组件引入
 * 2. 绑定引用变量
 * 3. 绑定update事件、
 * 4. onlyImage 默认过滤 可以设置
 * 例子： <ra-file-picker ref="refFilePicker" onlyImage @update="updateSelect" />
 * 5. 父组件通过调用 refFilePicker.vue.show() 展示选择界面
 * 6. 父组件通过函数 updateSelect 的参数获得选中的文件 url 或 url数组
 */
const props = defineProps({
  onlyImage: {
    type: Boolean,
    default: true,
  },
  multiple: {
    type: Boolean,
    default: true,
  },
});

const emit = defineEmits(['update']);
// 载入效果
const loading = ref(false);
// 显示弹窗
const show = ref(false);
// 表单
const refForm = ref();
// 查询到的文件列表
const files = ref([]);
// 搜索栏
const searchForm = ref();
// 选中的文件 ID 数组
const selectedFiles = ref([]);
const selectedFileIds = ref([]);

// 查询参数
const formParams = reactive({
  keyword: '',
  mime: props.onlyImage ? 'image' : '',
});
// 搜索参数
const pageParams = reactive({
  currentPage: 1,
  pageSize: 50,
  total: null,
});

// 复位查询
const resetForm = () => {
  refForm.value.resetFields();
};

// 数据加载
const loadFiles = async () => {
  try {
    formParams.current_page = pageParams.currentPage;
    formParams.page_size = pageParams.pageSize;
    const result = await AdminFileAPI.index(formParams);
    const {
      current_page: currentPage,
      per_page: pageSize,
      total,
      data,
    } = result.data;
    Object.assign(pageParams, { currentPage, pageSize, total });
    files.value = data;
  } catch (error) {
    console.error('Failed to fetch files:', error);
  }
};

// 切换选中状态
const toggleSelection = (file) => {
  const index = selectedFileIds.value.indexOf(file.id);
  if (!props.multiple && selectedFileIds.value.length >= 1 && index === -1) {
    ElMessage.error($t('common.message.validate.only_single_select'));
    return;
  }
  if (index === -1) {
    selectedFiles.value.push(file);
    selectedFileIds.value.push(file.id);
  } else {
    selectedFiles.value.splice(index, 1);
    selectedFileIds.value.splice(index, 1);
  }
};

// 检查文件是否被选中
const isSelected = computed(() => (id) => selectedFileIds.value.includes(id));

/**
 * 分页变化
 */
const pageChangeEvent = (e) => {
  pageParams.current_page = e.currentPage;
  pageParams.page_size = e.pageSize;
  loadFiles();
};

/**
 * 文件上传
 */
const refRaUpload = ref();
const handleUpload = () => {
  refRaUpload.value.show();
};

/**
 * 批量删除文件
 */
const handleDelete = () => {
  ElMessageBox.confirm(
    $t('common.message.confirm.general', {
      action: $t('common.action.delete'),
    }),
    $t('common.title.delete'),
    {
      type: 'warning',
    },
  )
    .then(() => {
      AdminFileAPI.delete({ id: selectedFileIds.value }).then(() => {
        ElMessage({
          type: 'success',
          message: $t('common.message.success.general', {
            action: $t('common.action.delete'),
          }),
        });
        loadFiles();
      });
    })
    .catch(() => {
      ElMessage({
        type: 'info',
        message: $t('common.message.cancel.general', {
          action: $t('common.action.delete'),
        }),
      });
    });
};

/**
 * 选中提交
 */
const selectedConfirm = () => {
  show.value = false;
  resetForm();
  emit('update', selectedFiles.value);
  selectedFiles.value = [];
  selectedFileIds.value = [];
};

/**
 * 取消
 */
const selectedCancel = () => {
  show.value = false;
  resetForm();
  selectedFiles.value = [];
  selectedFileIds.value = [];
};

/**
 * 暴露方法
 */
defineExpose({
  show() {
    loadFiles();
    // 展示表单
    show.value = true;
    // 重置表单
    nextTick(() => {
      resetForm();
    });
  },
});
</script>
<style lang="scss" scoped>
.page-container {
  width: 100%;
  padding: 5px;
  border-radius: 4px;
  background-color: var(--el-bg-color-overlay);
  .search-form {
    display: flex;
    flex-wrap: wrap;
    margin-bottom: 5px;
    width: 100%;
    justify-content: flex-start;
    @media (max-width: 768px) {
      display: none; /* 当屏幕宽度小于等于 768px 时隐藏表单 */
    }
  }
  .grid-container {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
    gap: 5px;
    padding: 5px;
    // background-color: #fff;
    overflow-y: auto; /* 只允许垂直滚动 */
    overflow-x: hidden; /* 隐藏水平滚动条 */
    align-items: start; /* 内容靠顶部对齐 */
    grid-auto-rows: 170px; /* 固定行高 */
    height: 100%;
  }
  .card-container {
    position: relative;
    cursor: pointer;
    height: 160px;
    position: relative;
    text-align: center;
    // background-color: #fff;
    width: 100%;
    .image-container {
      border-radius: 2px;
      height: 100px;
      width: 100px;
    }
    .font-image {
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .title {
      font-size: 12px;
      // color: #333;
      text-align: center;
    }
    // // 选中标记
    // &.selected::before {
    //   content: '';
    //   position: absolute;
    //   top: 0;
    //   right: 0;
    //   width: 0;
    //   height: 0;
    //   border-top: 30px solid #67c23a;
    //   border-left: 30px solid transparent;
    //   border-bottom: 30px solid transparent;
    //   z-index: 10;
    // }

    // &.selected::after {
    //   content: '✓';
    //   position: absolute;
    //   top: -2px;
    //   right: 3px;
    //   color: #fff;
    //   font-size: 14px;
    //   font-weight: bold;
    //   z-index: 11;
    // }

    // 选中标记
    &.selected::before {
      content: '';
      position: absolute;
      top: 0;
      right: 0;
      width: 100%;
      height: 100%;
      border-radius: 2px;
      border: 2px solid #67c23a;
      z-index: 10;
    }

    &.selected::after {
      content: '✓';
      position: absolute;
      top: -2px;
      right: 3px;
      color: #67c23a;
      font-size: 24px;
      font-weight: bold;
      z-index: 11;
    }
  }
  .empty-state {
    display: flex;
    flex-grow: 1;
    justify-content: center;
    align-items: center;
    height: 100%;
    width: 100%;
    grid-column: 1 / -1; /* 占据所有列 */
    grid-row: 1 / -1; /* 占据所有行 */
  }
}
</style>
